package com.cloud.base.classloader;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class HotDeploymentPlug {
    public static void main(String[] args) {
        HotDeploymentPlug hotDeploymentPlug = new HotDeploymentPlug("D:\\code\\meite-jvm\\com\\mayikt\\days01");
        hotDeploymentPlug.listener();
    }

    //存放所有的class文件
    private Map<String, ClassFileEntity> mapClassFiles = new HashMap<>();
    private String path;
    /**
     * 包的名称
     */
    private String packageName = "com.mayikt.days01.";

    public HotDeploymentPlug(String path) {
        this.path = path;
    }

    public void start() {
        listener();
    }

    /**
     * 监听方法
     */
    public void listener() {
        new Thread(() -> {
            while (true) {
                // 1.读取该文件下
                File files = new File(path);
                File[] tempList = files.listFiles();
                // 2.读取class文件 存入到 mapClassFiles
                for (File file :
                        tempList) {
                    String name = file.getName();
                    if (StringUtils.isEmpty(name)) {
                        continue;
                    }
                    long l = file.lastModified();
                    // 使用类加载器读取该 class
                    String className = packageName + name.replace(".class", "");
                    if (mapClassFiles.containsKey(className)) {
                        // 则比对该class文件 是否被修改
                        ClassFileEntity mapClassFileEntity = mapClassFiles.get(className);
                        if (mapClassFileEntity.getLastModified() != l) {
                            try {
                                mapClassFileEntity.setLastModified(l);
                                MayiktClassLoader mayiktClassLoader = new MayiktClassLoader(file);
                                Class<?> aClass = mayiktClassLoader.loadClass(className);
                                Object o = aClass.newInstance();
                                log.info(className + "class文件发生了变化");

                            } catch (Exception e) {
                                log.error("e:{}", e);
                            }
                        }
                    } else {
                        ClassFileEntity newClassFileEntity = new ClassFileEntity(className, l);
                        // 如果不存在 则存入到mapClassFiles集合中
                        mapClassFiles.put(className, newClassFileEntity);
                    }
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}
